package com.study.shiro.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.study.shiro.realm.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 陈烨庆
 * @date 2023/4/27
 */
@Configuration
public class ShiroConfig {

    @Autowired
    private MyRealm myRealm;

    /**
     * 配置 SecurityManager
     * @return
     */
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager() {
        // 1. 创建 defaultWebSecurityManager 对象
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();

        // 2. 创建加密对象 设置相关属性
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
            // 2.1. 采用 md5 加密
        matcher.setHashAlgorithmName("md5");
            // 2.2. 迭代加密的次数
        matcher.setHashIterations(3);

        // 3. 将加密对象存储到 myRealm 中
        myRealm.setCredentialsMatcher(matcher);

        // 4. 讲 myRealm 存入 defaultWebSecurityManager 对象
        defaultWebSecurityManager.setRealm(myRealm);

        // 5. 设置 rememberMe
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager());
        return defaultWebSecurityManager;
    }

    @Bean
    public DefaultShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
        // 不认证可以访问的资源  不需要授权、登录就可以访问。eg:/index
        defaultShiroFilterChainDefinition.addPathDefinition("/myController/userLogin", "anon");
        defaultShiroFilterChainDefinition.addPathDefinition("/login", "anon");

        // 登出过滤器 有顺序问题,要在登录之前  退出拦截器。退出成功后，会 redirect到设置的/URI
        defaultShiroFilterChainDefinition.addPathDefinition("/logout", "logout");

        // 需要登录认证的拦截范围  需要登录授权才能访问。eg：/用户中心
        defaultShiroFilterChainDefinition.addPathDefinition("/**", "authc");

        // 添加存在用户的过滤器(rememberMe)  用户拦截器。eg：登录后（authc），第二次没登陆但是有记住我(remmbner)都可以访问。
        defaultShiroFilterChainDefinition.addPathDefinition("/**", "user");

        return defaultShiroFilterChainDefinition;
    }

    @Bean
    public SimpleCookie rememberMeCookie() {
        SimpleCookie cookie = new SimpleCookie("rememberMe");
        // 设置跨域
        // cookie.setDomain(domain);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(30 * 24 * 60 * 60);
        return cookie;
    }

    /**
     * 创建 Shiro 的 cookie 管理对象
     * @return
     */
    @Bean
    public CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        cookieRememberMeManager.setCipherKey("1234567898765432".getBytes());
        return cookieRememberMeManager;
    }

    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

}
